const ffmpeg = require('fluent-ffmpeg');
const Jimp = require('jimp');
const QrCode = require('qrcode-reader');
const fs = require('fs');
const path = require('path');
const jsQR = require('jsqr');

const currentPath = path.resolve();
// 指定要读取的文件夹路径
const sourceFilePath = path.join(currentPath, '点评原文件');
const uploadingFilePath = path.join(currentPath, '待上传文件');

// 读取文件夹中的所有文件名
function getFilesInFolder(folder) {
  return new Promise((resolve, reject) => {
    fs.readdir(folder, (err, files) => {
      if (err) {
        reject(err);
      } else {
        resolve(files);
      }
    });
  });
}

// 提取第一帧的输出路径
const firstFramePath = 'first_frame.png';

// 提取视频的第一帧
function extractFirstFrame(videoPath, outputFramePath) {
  return new Promise((resolve, reject) => {
    ffmpeg(videoPath)
      .screenshots({
        timestamps: ['0'],
        filename: path.basename(outputFramePath),
        folder: path.dirname(outputFramePath),
        size: '2668x1500'
      })
      .on('end', resolve)
      .on('error', reject);
  });
}
// 读取并处理第一帧图像，识别二维码
async function recognizeQRCode2(imagePath) {
  const image = await Jimp.read(imagePath);
  const { data, width, height } = image.bitmap;
  const qrCode = jsQR(data, width, height);
  return qrCode ? qrCode.data : null;
}
// 读取并处理第一帧图像，识别二维码
function recognizeQRCode(imagePath) {
  return new Promise((resolve, reject) => {
    Jimp.read(imagePath, (err, image) => {
      if (err) {
        reject(err);
        return;
      }
      const qr = new QrCode();
      qr.callback = (err, value) => {
        if (err) {
          console.log('二维码识别失败 :', err);
          reject(err);
          return;
        }
        resolve(value ? value.result : null);
      };
      qr.decode(image.bitmap);
    });
  });
}

// 重命名视频文件
function renameFile(oldPath, newPath) {
  return new Promise((resolve, reject) => {
    fs.rename(oldPath, newPath, (err) => {
      if (err) {
        reject(err);
        return;
      }
      resolve();
    });
  });
}

// 主函数
async function processFile(inputFilePath) {
  console.log('')
  console.log('🚀🚀🚀🚀🚀')
  console.log('开始处理文件：', inputFilePath)
  const fileExt = path.extname(inputFilePath);
  let type = '';
  if (['.mov', '.MOV', '.mp4', '.MP4'].includes(fileExt)) {
    // 提取第一帧
    type = 'video';
  } else if (['.jpg', '.JPG', '.jpeg', '.JPEG', '.png', '.PNG', '.heic', '.HEIC'].includes(fileExt)) {
    type = 'image';
  }
  try {
    if (!type) {
      console.log('inputFilePath :', inputFilePath);
      throw new Error(`❌ 🚧🚧🚧 不支持的文件类型！！！`);
    }
    if (type === 'video') {
      await extractFirstFrame(inputFilePath, firstFramePath);
      console.log('✅ 从视频中提取第一帧成功');
    }
    // 识别二维码
    let qrCodeString = '';
    try {
      qrCodeString = await recognizeQRCode(type == 'video' ? firstFramePath : inputFilePath);
      console.log('✅ 二维码识别成功：', qrCodeString);
    } catch (error) {
      console.log('🚧🚧🚧 第一次二维码识别失败')
      try {
        console.log('🚧🚧🚧 尝试第二次识别')
        qrCodeString = await recognizeQRCode2(type == 'video' ? firstFramePath : inputFilePath);
        if (qrCodeString) {
          console.log('✅ 二维码二次识别成功 ', qrCodeString);
        } else {
          console.log('🚧🚧🚧 第二次二维码识别失败')
          throw new Error();
        }
      } catch (error) {
        throw new Error('❌ 🚧🚧🚧 二维码检测异常！！！', inputFilePath);
      }
    }
    // 从二维码中提取作品 id
    const qrCodeId = qrCodeString.split('id=')[1];
    if (!qrCodeId) {
      throw new Error('❌ 🚧🚧🚧 提取作品 id 失败！！！');
    } else {
      console.log('✅ 提取到作品 id:', qrCodeId);
    }
    // 构建新的视频文件路径
    const newFilePath = path.join(uploadingFilePath, type == 'video' ? `${qrCodeId}${fileExt}` : `${qrCodeId}${fileExt}`);
    // 文件重命名
    await renameFile(inputFilePath, newFilePath);
    console.log('✅ 文件已重命名：');
    console.log('✅ 原文件名称：', inputFilePath);
    console.log('✅ 名称修改为：', newFilePath);
    console.log('🎉🎉🎉🎉🎉🎉🎉🎉')
    console.log('============================================', )
  } catch (err) {
    console.error(err);
    console.log('')
  } finally {
    // 删除第一帧图片
    if (type === 'video') {
      fs.unlink(firstFramePath, (err) => {
        if (err) console.error('❌ 🚧🚧🚧 删除第一帧图片失败：', err.message);
      });
    }
  }
}

const main = async () => {
  const files = await getFilesInFolder(sourceFilePath);
  console.log('files :', files);
  // 依次处理每个文件的异步任务
  for (const fileName of files) {
    await processFile(`${sourceFilePath}/${fileName}`)
  }
}

// 运行主函数
main()
